import { Viewer } from "cesium";
import * as Cesium from "cesium";
import { DynamicCircleDiffuseMaterial } from "../Materials/DynamicCircleDiffuseMaterial";

const viewerSatelliteMixin = (viewer: Viewer) => {
  if (!viewer.viewerMixins) {
    viewer.viewerMixins = {};
  }

  const viewerMixins = viewer.viewerMixins;

  const addInterferenceEffect = (
    target: string,
    main: string,
    color: string
  ) => {
    const mainEntity = viewer.entities.getById(main);
    const targetEntity = viewer.entities.getById(target);

    if (mainEntity && targetEntity) {
      viewer.entities.add({
        name: "指向圆锥",

        label: {
          text: "干扰",
          font: "20px sans-serif",
          fillColor: Cesium.Color.WHITE, // 文字填充颜色
          outlineColor: Cesium.Color.BLACK, // 边框颜色
          outlineWidth: 4, // 边框宽度
          style: Cesium.LabelStyle.FILL_AND_OUTLINE, // 同时显示填充和边框
          // 可选的其他样式
          verticalOrigin: Cesium.VerticalOrigin.CENTER,
          horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
          pixelOffset: new Cesium.Cartesian2(-20, -50), // 偏移量
          eyeOffset: new Cesium.Cartesian3(0, 0, 200),
        },
        position: new Cesium.CallbackPositionProperty((time) => {
          const pos0 = mainEntity.position!.getValue(time);
          const pos1 = targetEntity.position!.getValue(time);
          if (pos0 && pos1) {
            return Cesium.Cartesian3.midpoint(
              pos0,
              pos1,
              new Cesium.Cartesian3()
            );
          }
          return new Cesium.Cartesian3();
        }, false),
      });
      viewer.entities.add({
        name: "指向圆锥",
        position: new Cesium.CallbackPositionProperty((time) => {
          const pos0 = mainEntity.position!.getValue(time);
          const pos1 = targetEntity.position!.getValue(time);
          if (pos0 && pos1) {
            return Cesium.Cartesian3.midpoint(
              pos0,
              pos1,
              new Cesium.Cartesian3()
            );
          }
          return new Cesium.Cartesian3();
        }, false),
        cylinder: {
          length: new Cesium.CallbackProperty((time) => {
            const pos0 = mainEntity.position!.getValue(time);
            const pos1 = targetEntity.position!.getValue(time);
            if (pos0 && pos1) {
              return Cesium.Cartesian3.distance(pos0, pos1);
            }
            return 0;
          }, false),
          topRadius: 0,
          bottomRadius: new Cesium.CallbackProperty((time) => {
            const pos0 = mainEntity.position!.getValue(time);
            const pos1 = targetEntity.position!.getValue(time);
            if (pos0 && pos1) {
              return Cesium.Cartesian3.distance(pos0, pos1) / 10;
            }
            return 0;
          }, false),
          material: new DynamicCircleDiffuseMaterial({
            color: color,
            duration: 300,
          }),
        },
        orientation: new Cesium.CallbackProperty((time) => {
          const pos0 = mainEntity.position!.getValue(time);
          const pos1 = targetEntity.position!.getValue(time);
          if (pos0 && pos1) {
            // 计算中点
            const midPoint = Cesium.Cartesian3.midpoint(
              pos0,
              pos1,
              new Cesium.Cartesian3()
            );

            // 计算从中点到目标点的方向向量
            const direction = Cesium.Cartesian3.subtract(
              pos1,
              midPoint,
              new Cesium.Cartesian3()
            );
            Cesium.Cartesian3.normalize(direction, direction);

            // 由于圆柱体默认朝向是 Z 轴，我们需要计算从 Z 轴到目标方向的旋转
            const defaultDirection = Cesium.Cartesian3.UNIT_Z;

            // 计算旋转轴（叉积）
            const rotationAxis = Cesium.Cartesian3.cross(
              defaultDirection,
              direction,
              new Cesium.Cartesian3()
            );
            Cesium.Cartesian3.normalize(rotationAxis, rotationAxis);

            // 计算旋转角度（点积）
            const dot = Cesium.Cartesian3.dot(defaultDirection, direction);
            const angle = Math.acos(Cesium.Math.clamp(dot, -1, 1));

            // 创建从 Z 轴到目标方向的四元数旋转
            return Cesium.Quaternion.fromAxisAngle(rotationAxis, angle);
          }
          return Cesium.Quaternion.IDENTITY;
        }, false),
      });
    }
  };
  const addDetectionEffect = (target: string, main: string, color: string) => {
    const mainEntity = viewer.entities.getById(main);
    const targetEntity = viewer.entities.getById(target);
    if (mainEntity && targetEntity) {
      viewer.entities.add({
        name: "指向圆锥",

        label: {
          text: "探测",
          font: "20px sans-serif",
          fillColor: Cesium.Color.WHITE, // 文字填充颜色
          outlineColor: Cesium.Color.BLACK, // 边框颜色
          outlineWidth: 4, // 边框宽度
          style: Cesium.LabelStyle.FILL_AND_OUTLINE, // 同时显示填充和边框
          // 可选的其他样式
          verticalOrigin: Cesium.VerticalOrigin.CENTER,
          horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
          pixelOffset: new Cesium.Cartesian2(-80, -30), // 偏移量
          eyeOffset: new Cesium.Cartesian3(0, 0, 200),
        },
        position: new Cesium.CallbackPositionProperty((time) => {
          const pos0 = mainEntity.position!.getValue(time);
          const pos1 = targetEntity.position!.getValue(time);
          if (pos0 && pos1) {
            return Cesium.Cartesian3.midpoint(
              pos0,
              pos1,
              new Cesium.Cartesian3()
            );
          }
          return new Cesium.Cartesian3();
        }, false),
      });

      viewer.entities.add({
        name: "激光",
        position: new Cesium.CallbackPositionProperty((time) => {
          const pos0 = mainEntity.position!.getValue(time);
          const pos1 = targetEntity.position!.getValue(time);
          if (pos0 && pos1) {
            return Cesium.Cartesian3.midpoint(
              pos0,
              pos1,
              new Cesium.Cartesian3()
            );
          }
          return new Cesium.Cartesian3();
        }, false),
        cylinder: {
          length: new Cesium.CallbackProperty((time) => {
            const pos0 = mainEntity.position!.getValue(time);
            const pos1 = targetEntity.position!.getValue(time);
            if (pos0 && pos1) {
              return Cesium.Cartesian3.distance(pos0, pos1);
            }
            return 0;
          }, false),
          topRadius: 0,
          bottomRadius: new Cesium.CallbackProperty((time) => {
            const pos0 = mainEntity.position!.getValue(time);
            const pos1 = targetEntity.position!.getValue(time);
            if (pos0 && pos1) {
              return Cesium.Cartesian3.distance(pos0, pos1) / 5;
            }
            return 0;
          }, false),
          material: Cesium.Color.fromCssColorString(color).withAlpha(0.3),
          slices: 4,
          outline: true,
          outlineColor: Cesium.Color.fromCssColorString("#fff"),
        },
        orientation: new Cesium.CallbackProperty((time) => {
          const pos0 = mainEntity.position!.getValue(time);
          const pos1 = targetEntity.position!.getValue(time);
          if (pos0 && pos1) {
            // 计算中点
            const midPoint = Cesium.Cartesian3.midpoint(
              pos0,
              pos1,
              new Cesium.Cartesian3()
            );

            // 计算从中点到目标点的方向向量
            const direction = Cesium.Cartesian3.subtract(
              pos1,
              midPoint,
              new Cesium.Cartesian3()
            );
            Cesium.Cartesian3.normalize(direction, direction);

            // 由于圆柱体默认朝向是 Z 轴，我们需要计算从 Z 轴到目标方向的旋转
            const defaultDirection = Cesium.Cartesian3.UNIT_Z;

            // 计算旋转轴（叉积）
            const rotationAxis = Cesium.Cartesian3.cross(
              defaultDirection,
              direction,
              new Cesium.Cartesian3()
            );
            Cesium.Cartesian3.normalize(rotationAxis, rotationAxis);

            // 计算旋转角度（点积）
            const dot = Cesium.Cartesian3.dot(defaultDirection, direction);
            const angle = Math.acos(Cesium.Math.clamp(dot, -1, 1));

            // 创建从 Z 轴到目标方向的四元数旋转
            return Cesium.Quaternion.fromAxisAngle(rotationAxis, angle);
          }
          return Cesium.Quaternion.IDENTITY;
        }, false),
      });
    }
  };
  const addLaserEffect = (target: string, main: string, color: string) => {
    const mainEntity = viewer.entities.getById(main);
    const targetEntity = viewer.entities.getById(target);

    if (mainEntity && targetEntity) {
      viewer.entities.add({
        name: "指向圆锥",

        label: {
          text: "激光",
          font: "20px sans-serif",
          fillColor: Cesium.Color.WHITE, // 文字填充颜色
          outlineColor: Cesium.Color.BLACK, // 边框颜色
          outlineWidth: 4, // 边框宽度
          style: Cesium.LabelStyle.FILL_AND_OUTLINE, // 同时显示填充和边框
          // 可选的其他样式
          verticalOrigin: Cesium.VerticalOrigin.CENTER,
          horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
          pixelOffset: new Cesium.Cartesian2(-50, -30), // 偏移量
          eyeOffset: new Cesium.Cartesian3(0, 0, 200),
        },
        position: new Cesium.CallbackPositionProperty((time) => {
          const pos0 = mainEntity.position!.getValue(time);
          const pos1 = targetEntity.position!.getValue(time);
          if (pos0 && pos1) {
            return Cesium.Cartesian3.midpoint(
              pos0,
              pos1,
              new Cesium.Cartesian3()
            );
          }
          return new Cesium.Cartesian3();
        }, false),
      });
      viewer.entities.add({
        name: "激光",
        polyline: {
          width: 20,
          positions: new Cesium.CallbackProperty((time) => {
            const pos0 = mainEntity.position!.getValue(time);
            const pos1 = targetEntity.position!.getValue(time);
            return [pos0, pos1];
          }, false),
          material: new Cesium.PolylineGlowMaterialProperty({
            // glowPower: 0.2,
            // taperPower: 0.5,
            color: Cesium.Color.fromCssColorString(color),
          }),
          arcType: Cesium.ArcType.NONE,
        },
      });
    }
  };

  Object.defineProperties(viewerMixins, {
    addInterferenceEffect: {
      get: function () {
        return addInterferenceEffect;
      },
    },
    addDetectionEffect: {
      get: function () {
        return addDetectionEffect;
      },
    },
    addLaserEffect: {
      get: function () {
        return addLaserEffect;
      },
    },
  });
};

export default viewerSatelliteMixin;
